package org.cos.verifier.ui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;

import org.cos.verifier.automata.Automata;
import org.cos.verifier.automata.AutomataParser;
import org.cos.verifier.process.ProfileManager;
import org.cos.verifier.process.Rule;
import org.cos.verifier.process.RuleManager;
import org.cos.verifier.utility.Activity;
import org.cos.verifier.utility.Encryptor;
import org.cos.verifier.utility.IOWrapper;
import org.cos.verifier.utility.ProgressBar;
import org.cos.verifier.utility.Timer;
import org.cos.verifier.utility.TimerListener;

public class CheckProgressDlg extends Frame implements TimerListener {
	class CheckActivity extends Activity {
		private Automata model;
		private AutomataParser ap;

		public CheckActivity(int target) {
			super(target);
			ap = new AutomataParser();
		}

		public void load_model(String model_file) {
			String content = "";
			try {
				byte[] data = Encryptor.decrypt(IOWrapper.get_inst().read_file(model_file));
				content = new String(data);
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			ap.parse(content);
			model = ap.get_automata();
		}

		public void run() {
			int i = 0;
			Hashtable profile = ProfileManager.get_inst().crr_profile();
			Hashtable rules = RuleManager.get_inst().get_all_rule();
			for (Enumeration ex=profile.keys(); ex.hasMoreElements() && !interrupted();) {
				try {
					sleep(10);
					String rule_name = (String) ex.nextElement();
					int chked = ((Integer) profile.get(rule_name)).intValue();
					if (chked != 0) {// activity rule
						Rule r = (Rule) rules.get(rule_name);
						System.out.println("check:" + rule_name);
						if (check(r.content)) {
							String str = "┬与规则[" + r.name + "]发生冲突:";
							me.info.add(str);
							me.info.add("└" + r.describ);
							LogDlg.get_inst().log(str);
						}
					}
				} catch (InterruptedException e) {
					// System.out.println("Activity error");
					return;
				}
				current++;
			}
		}

		public boolean check(String policy_xml) {
			ap.parse(policy_xml);
			Automata policy = ap.get_automata();
			Automata result = model.merge(policy);
			//result.print();
			//result.print_dot();
			return result.check();
		}
	}

	String msg;
	Button cancel_btn;
	CheckProgressDlg me;
	CheckActivity activity;
	Timer timer;
	ProgressBar pb;
	Panel header;
	Label title;
	List info;

	public CheckProgressDlg() {
		this.me = this;
		me.setLayout(new BorderLayout());
		header = new Panel();
		header.setLayout(new GridLayout(2, 1));
		title = new Label("正在校验模型...");
		pb = new ProgressBar();
		header.add(title);
		header.add(pb);

		info = new List();

		cancel_btn = new Button("终止校验");
		cancel_btn.addActionListener(new CancelHandle());
		
		//TODO ui fix
		me.add(header, BorderLayout.NORTH);
		me.add(info, BorderLayout.CENTER);
		me.add(cancel_btn, BorderLayout.SOUTH);
		me.setSize(300, 400);
		me.addWindowListener(new FrameHandler());
	}

	public void reset_timer() {
		if (timer == null) {
			timer = new Timer(10, this);
			timer.start();
		}
	}

	public void time_elapsed(Timer t) {
		int current = activity.getCurrent();
		pb.setLevel(current);
		if (current >= activity.getTarget()) {
			on_finished();
		}
		repaint();
	}

	private void on_finished() {
		timer.interrupt();
		activity.interrupt();
		//timer = null; // CRITICAL
		//activity = null;
		cancel_btn.setEnabled(false);
		title.setText(title.getText() + "完成.");
		me.info.add("校验完毕");
		LogDlg.get_inst().log("校验完毕");
	}

	private void on_start(String model_file) {
		int max = ProfileManager.get_inst().crr_profile().size();
		pb.setLevel(0);
		pb.setMaximum(max);
		activity = new CheckActivity(max);
		activity.load_model(model_file);
		activity.start();
		reset_timer();
		cancel_btn.setEnabled(true);
	}

	private void on_cancel() {
		timer.interrupt();
		//timer = null; // CRITICAL
		activity.interrupt();
		//activity = null;
		info.add("操作被取消！");
		title.setText(title.getText() + "取消.");
		cancel_btn.setEnabled(false);
		LogDlg.get_inst().log("操作被取消");
	}

	public void display(String model_file) {
		this.setVisible(true);
		on_start(model_file);
	}

	class CancelHandle implements ActionListener {
		public void actionPerformed(ActionEvent arg0) {
			on_cancel();
		}
	}

	class FrameHandler extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			me.dispose();
		}
	}
}
